/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 *
 * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
 *
 * Contributor(s): 
 *  Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
 *  
 * If you didn't download this code from the following link, you should check
 * if you aren't using an obsolete version: http://www.isqlviewer.com
 */
package org.isqlviewer.ui.wizards.service;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Set;

import javax.swing.Box;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.isqlviewer.sql.ConnectionProfile;
import org.isqlviewer.sql.JdbcService;
import org.isqlviewer.sql.embedded.EmbeddedDatabase;
import org.isqlviewer.swing.SwingUtilities;
import org.isqlviewer.ui.wizards.AbstractWizardStep;
import org.isqlviewer.ui.wizards.WizardContext;
import org.isqlviewer.util.IsqlToolkit;
import org.isqlviewer.util.LocalMessages;

public class ConfigureBasicServiceOptions extends AbstractWizardStep implements ActionListener {

    private LocalMessages messages = new LocalMessages(ServiceWizard.BUNDLE_NAME);
    private JTextField serviceName = null;
    private JTextField serviceDriver = null;
    private JTextField serviceURL = null;
    private JTextField serviceExampleURL = null;
    private JTextField servicePrincipal = null;
    private JTextField serviceCredentials = null;
    private JCheckBox useAuthenticationPrompt = null;
    private Properties driverMappings = IsqlToolkit.getDefaultDriverDefinitions();

    public void actionPerformed(ActionEvent event) {

        String command = event.getActionCommand();
        if ("1".equals(command)) {
            boolean flag = servicePrincipal.isEnabled();
            servicePrincipal.setEnabled(!flag);
            servicePrincipal.setEditable(!flag);
            serviceCredentials.setEnabled(!flag);
            serviceCredentials.setEditable(!flag);
        } else {
            String className = serviceDriver.getText();
            String defaultExample = messages.getMessage("newservicewizard.jdbcurlexample.notavailable");
            String exampleURL = driverMappings.getProperty(className, defaultExample);
            serviceExampleURL.setText(exampleURL);
        }
    }

    @Override
    public void activate(WizardContext context) {

        super.activate(context);
        JdbcService service = (JdbcService) context.getAttribute(ServiceWizard.ATTRIBUTE_SERVICE);
        if (service == null) {
            return;
        }
        serviceURL.setText(service.getUrl());
        serviceName.setText(service.getName());

        String principal = service.getPrincipal();
        String credentials = service.getCredentials();
        boolean usePrompt = principal == null && credentials == null;
        if (!usePrompt) {
            servicePrincipal.setText(principal);
            serviceCredentials.setText(credentials);
        } else {
            servicePrincipal.setText("");
            serviceCredentials.setText("");
        }
        useAuthenticationPrompt.setSelected(usePrompt);
        servicePrincipal.setEnabled(!usePrompt);
        servicePrincipal.setEditable(!usePrompt);
        serviceCredentials.setEnabled(!usePrompt);
        serviceCredentials.setEditable(!usePrompt);

        String className = service.getDriverClass();
        if (className != null) {
            serviceDriver.setText(className);
            String defaultExample = messages.getMessage("newservicewizard.jdbcurlexample.notavailable");
            String exampleURL = driverMappings.getProperty(className, defaultExample);
            serviceExampleURL.setText(exampleURL);
        }
    }

    public boolean isFirst() {

        return false;
    }

    public boolean isLast() {

        return false;
    }

    @Override
    public void init(WizardContext context) {

        super.init(context);
        setTitle(messages.getMessage("newservicewizard.configure-service-details.title"));
        setComment(messages.getMessage("newservicewizard.configure-service-details.tip"));
        setImage(SwingUtilities.loadIconResource(ServiceWizard.class, "database", 22));

        GridBagConstraints constraint = null;
        String title = null;
        String tip = null;
        JLabel label = null;

        JPanel panel = new JPanel(new GridBagLayout());
        setView(panel);

        title = messages.format("newservicewizard.servicename.title");
        tip = messages.format("newservicewizard.servicename.tip");
        JComponent component = new JTextField(32);
        serviceName = ((JTextField) component);
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(component);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        title = messages.format("newservicewizard.jdbcdriver.title");
        tip = messages.format("newservicewizard.jdbcdriver.tip");
        DefaultComboBoxModel model = new DefaultComboBoxModel();
        JComboBox comboSupport = new JComboBox();
        comboSupport.setModel(model);
        component = (JTextField) comboSupport.getEditor().getEditorComponent();

        Set<Object> driverClasses = driverMappings.keySet();
        for (Object className : driverClasses) {
            model.addElement(className);
        }
        comboSupport.addActionListener(this);
        comboSupport.setMaximumRowCount(5);
        comboSupport.setEditable(true);
        serviceDriver = ((JTextField) component);
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(comboSupport);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(comboSupport, constraint);

        title = messages.format("newservicewizard.jdbcurlexample.title");
        tip = messages.format("newservicewizard.jdbcurlexample.tip");
        component = new JTextField();
        ((JTextField) component).setEditable(false);

        serviceExampleURL = ((JTextField) component);
        component.setToolTipText(tip);
        component.setFont(component.getFont().deriveFont(Font.ITALIC));
        constraint = ServiceWizard.constrain(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(component);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        String defaultExample = messages.getMessage("newservicewizard.jdbcurlexample.notavailable");
        String exampleURL = driverMappings.getProperty(serviceDriver.getText(), defaultExample);
        serviceExampleURL.setText(exampleURL);

        title = messages.format("newservicewizard.jdbcurl.title");
        tip = messages.format("newservicewizard.jdbcurl.tip");
        component = new JTextField();
        serviceURL = ((JTextField) component);
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(component);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        title = messages.format("newservicewizard.principal.title");
        tip = messages.format("newservicewizard.principal.tip");
        component = new JTextField();
        servicePrincipal = ((JTextField) component);
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(component);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 5, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        title = messages.format("newservicewizard.credentials.title");
        tip = messages.format("newservicewizard.credentials.tip");
        component = new JPasswordField();
        serviceCredentials = ((JTextField) component);
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        label = new JLabel(title);
        label.setLabelFor(component);
        panel.add(label, constraint);
        constraint = ServiceWizard.constrain(1, 6, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        title = messages.format("newservicewizard.use_authentication_prompt.title");
        tip = messages.format("newservicewizard.use_authentication_prompt.tip");

        component = new JCheckBox(title);
        useAuthenticationPrompt = (JCheckBox) component;
        ((JCheckBox) component).setActionCommand(Integer.toString(1));
        ((JCheckBox) component).addActionListener(this);
        ((JCheckBox) component).doClick();
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 4, 2, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL);
        panel.add(component, constraint);

        component = (JComponent) Box.createVerticalGlue();
        component.setName("GLUE");
        component.setToolTipText(tip);
        constraint = ServiceWizard.constrain(0, 7, 2, 1, 0.0, 1.0, GridBagConstraints.CENTER,
                GridBagConstraints.VERTICAL);
        panel.add(component, constraint);
    }

    public boolean isValid(WizardContext context) {

        JdbcService service = (JdbcService) context.getAttribute(ServiceWizard.ATTRIBUTE_SERVICE);
        EmbeddedDatabase edb = EmbeddedDatabase.getSharedInstance();
        boolean isValid = true;
        String text = serviceName.getText().trim();
        boolean exists = true;
        try {
            exists = edb.getServiceIDForName(text) < 0;
        } catch (SQLException e) {
        }

        if (text.length() == 0 || exists) {
            if (text.length() == 0) {
                context.showInformationDialog(messages.getMessage("newservicewizard.name-blank.error"));
            } else {
                context.showInformationDialog(messages.getMessage("newservicewizard.name-registerd.error"));
            }
            context.markTextComponentIncorrect(serviceName);
            isValid = false;
        } else {
            context.unmarkTextComponentIncorrect(serviceName);
        }

        text = serviceURL.getText().trim();
        if (text.length() == 0) {
            context.showInformationDialog(messages.getMessage("newservicewizard.url-blank.error"));
            context.markTextComponentIncorrect(serviceURL);
            isValid = false;
        } else {
            context.unmarkTextComponentIncorrect(serviceURL);
        }

        text = serviceDriver.getText().trim();
        if (text.length() == 0) {
            context.showInformationDialog(messages.getMessage("newservicewizard.driver-blank.error"));
            context.markTextComponentIncorrect(serviceDriver);
            isValid = false;
        } else {
            context.unmarkTextComponentIncorrect(serviceDriver);
        }

        if (isValid) {
            service.setName(serviceName.getText());
            service.setUrl(serviceURL.getText());
            service.setDriverClass(serviceDriver.getText());
            ConnectionProfile profile = service.getProfile();
            profile.setCredentialsPersistent(false);
            if (serviceCredentials.isEnabled()) {
                String credentials = new String(((JPasswordField) serviceCredentials).getPassword());
                service.setCredentials(credentials);
                service.setPrincipal(servicePrincipal.getText());
                profile.setCredentialsPersistent(true);
            }
        }
        return isValid;
    }
}